import cgi
import sha
from django.utils import simplejson as json
from time import time
from datetime import datetime
from google.appengine.api import memcache
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
from google.appengine.api import mail
import os
import time
import facebook
import xml.etree.cElementTree as etree
import urllib
import time

from google.appengine.ext.webapp import template
from google.appengine.api import urlfetch

from constants import *
from tickets import *
from models import *
from django.views import static
import shared

_FbApiKey = '102d3b67b1e319439396fed4c2e0eb58'
_FbSecret = 'cecf1af6fefde54784a9ff34b2403a37'
_LastfmApiKey = 'ed892c0f6430d25a96238ed1c87e2920'
_LastfmSecret = '91df7d1a616f1ab38b8635e660c02bd7'


class ConcertSearch(webapp.RequestHandler):
    def get(self):
        artist = self.request.get('artist')
        venue = self.request.get('venue')
        date = self.request.get('date')
        template_values = {
             'artist': artist,
             'venue': venue,
             'date': date
        }
        path = os.path.join(os.path.dirname(__file__), 'html/concert_search.html')
        self.response.out.write(template.render(path, template_values))

        
class ArtistSearch(webapp.RequestHandler):
    def post(self):
        #Decode URL
        artists = []
        artist = self.request.get('artist')
        
        #generate api call
        url = 'http://ws.audioscrobbler.com/2.0/?method=artist.search&artist='
        url = url + urllib.quote(artist)
        url = url + '&api_key='+_LastfmApiKey
        
        result = urlfetch.fetch(url)
        
        dom = etree.fromstring(result.content)
        
        all_results = dom.findall('.//artist')
        for artist in all_results:
            imgs = artist.findall('.//image')
            img_txt = ""
            for img in imgs:
                attr = img.attrib
                if (attr['size'] == 'large'):
                    img_txt = img.text
                    break
            if (img_txt is None or img_txt == "" or img_txt == "null"):
                img_txt = shared.default_image
            dat = {
                'name' : artist.findtext('.//name'),
                'url' : 'http://' + artist.findtext('.//url'),
                'image' : img_txt
            }
            artists.append(dat)
        
        self.response.out.write(json.dumps(artists))
        
class EventSearch(webapp.RequestHandler):
    def get(self):
        artist = self.request.get('artist')
        location = self.request.get('location')
        distance = self.request.get('distance')
        events = []
        if(artist != ""):
            url = 'http://ws.audioscrobbler.com/2.0/?method=artist.getevents&artist='
            url = url + urllib.quote(artist)
            url = url + '&api_key='+_LastfmApiKey
            
        elif (location != ""):
            url = 'http://ws.audioscrobbler.com/2.0/?method=geo.getevents&location='
            url += urllib.quote(location)
            if(distance != ""):
                url += "&distance=" + urllib.quote(distance)
            url += '&api_key='+_LastfmApiKey
            
            
        result = urlfetch.fetch(url)   
        dom = etree.fromstring(result.content)
        
        attr = dom.findall('.//events') 
        attr = attr[0]
        attr = attr.attrib
        totalpages = int(attr['total'])
        
        all_results = dom.findall('.//event')
        for event in all_results:
            date = event.findtext('.//startDate')
            dt = time.strptime(date, "%a, %d %b %Y %H:%M:%S");
            
            ystr = str(dt[0]);
            mstr = str(dt[1]);
            dstr = str(dt[2]);
            if len(mstr) == 1:
                mstr = "0" + mstr
            if len(dstr) == 1:
                dstr = "0" + dstr
            
            dt = "" + ystr + "-" + mstr + "-" + dstr;
            dat = {
                   'title' : event.findtext('.//title'),
                   'artist' : event.findtext('.//headliner'),
                   'venue' : event.findtext('./venue/name'),
                   'city' : event.findtext('./venue/location/city'),
                   'country' : event.findtext('./venue/location/country'),
                   'date' : date,
                   'url' : event.findtext('./url'),
                   'simpleDate' : dt,
            }
            events.append(dat)
        
        self.response.out.write(json.dumps(events))
        
    def post(self):
        EventSearch.get(self)

    
class GetAllArtists(webapp.RequestHandler):
    def get(self):
        artist_lst = memcache.get('all_artists')
        if artist_lst is not None:
            self.response.out.write(json.dumps(artist_lst))
        else:
            resetArtistList()
            artist_lst = memcache.get('all_artists')
            self.response.out.write(json.dumps(artist_lst))
    def post(self):
        GetAllArtists.get(self)
    
           
     
class AddArtist(webapp.RequestHandler):
    def get(self):
        name = self.request.get('name')
        id = self.request.get('id')        
        #instantiate facebook
        fb = facebook.Facebook(_FbApiKey, _FbSecret)
        
        if fb.check_session(self.request) and fb.added:
                pass
        else:
                # If not redirect them to your application add page.
                self.response.out.write(json.dumps([False,'http://apps.facebook.com/concert-deals/']))
                return

        
        fbUser = fb.users.getInfo( [fb.uid], ['uid', 'name'])[0]
        a = fb.uid;
        
        user = getUser(fbUser['uid'])
        retVal = False;
        if(id != ""):
            if (not existsInList(user.artist_ids, id)):
                user.artist_ids += [id]
                user.put()
                retVal=True
        else:
            artist = getArtist(name)
            if artist is not None:
                id = str(artist.key())
                if (not existsInList(user.artist_ids, id)):
                    user.artist_ids += [id]
                    user.put()
                    retVal = True
        self.response.out.write(json.dumps([True,retVal]))           
            
    def post(self):    
        AddArtist.get(self)
        
class RemoveArtist(webapp.RequestHandler):
    def get(self):
        artist = self.request.get('artist')
        save = self.request.get('save')
        fb = facebook.Facebook(_FbApiKey, _FbSecret)
        if fb.check_session(self.request) and fb.added:
                pass
        else:
                # If not redirect them to your application add page.
                self.response.out.write(json.dumps([False,'http://apps.facebook.com/concert-deals/']))
                return
        if(save == 'true'):
            RemoveArtist.commitUnfollows(self,fb.uid)
            self.response.out.write(json.dumps([True,artist.replace(" ", "_")]))
            return


        lst = memcache.get(str(fb.uid)+'_uflist')
        if (lst is not None):
            lst += [artist]
        else:
            lst = [artist]
        
        memcache.set(str(fb.uid)+'_uflist',lst)
        self.response.out.write(json.dumps([True,artist.replace(" ", "_")]))
        return
        
    def commitUnfollows(self,uid):
        lst = memcache.get(str(uid)+'_uflist')
        if lst is not None:
            user = getUser(int(uid))
            for elem in lst:
                    artist = getArtist(elem)
                    if artist is not None:
                        id = str(artist.key())
                        try:
                            user.artist_ids.remove(id)
                        except:
                            id ="" 
            user.put()
            memcache.delete(str(uid)+'_uflist')
        
    def post(self): 
        RemoveArtist.get(self)
         
                    
                
class FBMLPage(webapp.RequestHandler):
    def get(self):
        fb = facebook.Facebook(_FbApiKey, _FbSecret)
        url = fb.get_add_url('http://apps.facebook.com/concert_deals')
        url = '<fb:redirect url="' + url + '" />'
        template_values = {'data':url}
        path = os.path.join(os.path.dirname(__file__), 'html/fbml_page.html')
        self.response.out.write(template.render(path, template_values))
    def post(self):
        FBMLPage.get(self)
        
class GetFollowList(webapp.RequestHandler):
    def get(self):
        
        fb = facebook.Facebook(_FbApiKey, _FbSecret)
        if fb.check_session(self.request) and fb.added:
                pass
        else:
                # If not redirect them to your application add page.
                self.response.out.write(json.dumps([False,'http://apps.facebook.com/concert-deals/']))
                return

        # Get the information about the user.
        fbUser = fb.users.getInfo( [fb.uid], ['uid', 'name'])[0]
        user = getUser(fbUser['uid'])
        
        artists = []
        uflist = memcache.get(str(fb.uid)+'_uflist')
        if uflist is None:
            uflist = []
        needsCommit = False
        for artist_id in user.artist_ids:
            k = db.Key(encoded=artist_id)
            artist = db.get(k)
            if existsInList(uflist, artist.name):
                artist.uf = True
                needsCommit = True
            else:
                artist.uf = False
            artist.name_id = artist.name.replace(" ", "_")
            if artist.img is None or artist.img == "":
                artist.img = shared.default_image
            dat = {
            'name': artist.name,
            'img': artist.img,
            'uf'  : artist.uf,
            'name_id':artist.name_id,
            }
            artists.append(dat)
        
        self.response.out.write(json.dumps([True,artists,needsCommit]))
    def post(self):
        GetFollowList.get(self)
        
        
class MainPage(webapp.RequestHandler):
    def get(self):
        
        #instantiate facebook 
        fb = facebook.Facebook(_FbApiKey, _FbSecret)
        
        if fb.check_session(self.request) and fb.added:
                pass
        else:
                # If not redirect them to your application add page.
                url = fb.get_add_url('http://apps.facebook.com/concert-deals/')
                self.response.out.write('<script language="javascript">top.location.href="' + url + '"</script>')
                return
        
        # Get the information about the user.
        fbUser = fb.users.getInfo( [fb.uid], ['uid', 'name'])[0]
        a = fb.uid;
        template_values = {
            'name': fbUser['name'],
            }
        path = os.path.join(os.path.dirname(__file__), 'html/index.html')
        self.response.out.write(template.render(path, template_values))
    

            



application = webapp.WSGIApplication(
                                     [('/', MainPage),
                                      ('/concert_search',ConcertSearch),
                                      ('/get_artists',ArtistSearch),
                                      ('/get_events',EventSearch),
                                      ('/all_artists',GetAllArtists),
                                      ('/add_artist',AddArtist),
                                      ('/add_app',FBMLPage),
                                      ('/get_tickets', TicketList),
                                      ('/begin_track', BeginTrack),
                                      ('/update_tracks', UpdateTracks),
                                      ('/view_tracks', ViewTracks),
                                      #('/remove_tracks', RemoveTracks),
                                      ('/filter_tickets', FilterTickets),
                                      ('/remove_artist', RemoveArtist),
                                      ('/follow_list', GetFollowList)
                                     ],
                                     debug=True)

#A method which makes sure the user has logged on
#returns the facebook instance      
def fbRequest(self):
        #instantiate facebook
        fb = facebook.Facebook(_FbApiKey, _FbSecret)
        
        if fb.check_session(self.request):
                pass
        else:
                # If not redirect them to your application add page.
                url = fb.get_add_url()
                self.response.out.write('<fb:redirect url="' + url + '" />')
                return

        # Checks to make sure the user has added your application.
        if fb.added:
                pass
        else:
                # If not redirect them to your application add page.
                url = fb.get_add_url()
                self.response.out.write('<fb:redirect url="' + url + '" />')
                return
    

#Method which returns the user object for the fb id
#creates a new user object in case it doesnt exist
def getUser(fb_id):
        users = Users.gql("WHERE fb_id = :fbid", fbid = fb_id)

        if (users.count(1) == 0):
            newUser = Users()
            newUser.fb_id = fb_id
            newUser.put()
            return newUser
        return users.get()

#Method which returns the artist object for the name
#creates a new artist object in case it doesnt exist
def getArtist(name):
    if(name  == ""): return None
    artists = Artists.gql("WHERE name = :nm ", nm = name)
    if (artists.count(1) > 0):
        artist = artists.get()
        return artist
    else:
        artist = Artists()
        artist.name = name
        #generate api call
        url = 'http://ws.audioscrobbler.com/2.0/?method=artist.getimages&artist='
        url = url + urllib.quote(artist.name)
        url = url + '&api_key='+_LastfmApiKey
        result = urlfetch.fetch(url)
        if(result.content == ""): return None
        dom = etree.fromstring(result.content)
        img = dom.find('.//image')
        imgs = img.findall('.//size')
        for img in imgs:
            attr = img.attrib
            if(attr['name'] == 'largesquare'):
                artist.img = img.text
                break
        artist.put()
        resetArtistList()
        return artist
        
def existsInList(list,element):
    for elems in list:
        if element == elems:
            return True
    return False

#Resets the all artist list used for autocomplete
def resetArtistList():
    artists = Artists.all()
    artists = artists.fetch(10000);
    data = []
    for artist in artists:
        dat = {'name':artist.name, 'id':str(artist.key())}
        data.append(dat)
    memcache.set('all_artists',data)



def main():
    run_wsgi_app(application)
    
if __name__ == "__main__":
    main()